Python编程-数据可视化:第17章-使用Web API
github 官方参考链接
使用API调用请求的数据
https://api.github.com/search/repositories?q=language:python&sort=stars
这个调用返回GitHub当前托管了多少个Python项目,以及有关最受欢迎的Python仓库的信息。
url 说明
| 部分 | 说明 |
|---|---|
https://api.github.com/ |
将请求发送到GItHub网站中响应API调用的部分。 |
search/repositories |
让API搜索Github上所有仓库。 |
?q= |
q表示查询,而等号(=)让我们能够开始指定查询。 |
language:python |
表示只想获取主要语言为python 的仓库信息 |
&sort=stars |
表示将项目按照星级排序。 |
调用后结果
json 的格式和说明请参见JSON。
{
"total_count": 8952515,
"incomplete_results": true,
"items": [
{
"id": 63476337,
"node_id": "MDEwOlJlcG9zaXRvcnk2MzQ3NjMzNw==",
"name": "Python",
"full_name": "TheAlgorithms/Python",
| 输出 | 说明 |
|---|---|
| "total_count": 8952515 | GitHub 总共有8952515项目 |
| "incomplete_results": true | 请求是成功的,但是不完整 |
| "items": | 返回的items 就是github 最受欢迎的项目详细信息 |
安装Requests
使用IDE 下载包

或者使用命令行
python -m pip install --user requests
处理API 响应
下面来编写一个程序,它自动执行API调用并处理结果,以找出GitHub上星级最高的Python项目:
① import requests
# 执行API调用并存储响应。
② url = 'https://api.github.com/search/repositories?q=language:python&sort=stars'
③ headers = {'Accept': 'application/vnd.github.v3+json'}
r = requests.get(url, headers=headers)
⑤ print(f"Status code: {r.status_code}")
# 将API 响应赋给一个变量。
⑥ response_dict = r.json()
# 处理结果。
⑦ print(response_dict.keys())
| 序号 | 说明 |
|---|---|
| 1 | 导入requests 包 |
| 2 | 存储API调用的URL |
| 3 | 由于Github API 版本为第3版,所以要显示指定 |
| 4 | 使用requests.get 调用API |
| 5 | 如果调用成功会返回一个status_code |
| 6 | API 返回JSON 格式的信息,所以需要使用json() 方法转为一个字典 |
| 7 | 打印字典 |
输出:
Status code: 200
dict_keys(['total_count', 'incomplete_results', 'items'])
状态为200, 说明请求成功了。 字典包含三个键:'total_count','incomplete_results,'items'
处理响应字典
import requests
# 执行API调用并存储响应。
url = 'https://api.github.com/search/repositories?q=language:python&sort=stars'
headers = {'Accept': 'application/vnd.github.v3+json'}
r = requests.get(url, headers=headers)
print(f"Status code: {r.status_code}")
# 将API 响应赋给一个变量。
response_dict = r.json()
# 处理结果。
print(response_dict.keys())
# 打印github上python 项目的个数
print(f"Total repositories: {response_dict['total_count']}")
# 探索有关仓库的信息。
repo_dicts = response_dict['items']
print(f"Repositories returned: {len(repo_dicts)}")
# 研究第一个仓库。
#repo_dict = repo_dicts[0]
#print(f"\nKeys: {len(repo_dict)}")
for repo_dict in repo_dicts:
# print(key)
print(f"\nSelected information about first repository:")
print(f"Name: {repo_dict['name']}")
print(f"Owner: {repo_dict['owner']['login']}")
print(f"Stars: {repo_dict['stargazers_count']}")
print(f"Repository: {repo_dict['html_url']}")
print(f"Updated: {repo_dict['updated_at']}")
print(f"Description: {repo_dict['description']}")
监视API 的速率限制
{
"resources": {
"core": {
"limit": 60,
"remaining": 60,
"reset": 1665731894,
"used": 0,
"resource": "core"
},
"graphql": {
"limit": 0,
"remaining": 0,
"reset": 1665731894,
"used": 0,
"resource": "graphql"
},
"integration_manifest": {
"limit": 5000,
"remaining": 5000,
"reset": 1665731894,
"used": 0,
"resource": "integration_manifest"
},
"search": {
"limit": 10,
"remaining": 10,
"reset": 1665728354,
"used": 0,
"resource": "search"
}
},
"rate": {
"limit": 60,
"remaining": 60,
"reset": 1665731894,
"used": 0,
"resource": "core"
}
}
Warning
这里关注一下search 的限制。limit : 每分钟10 个请求。在当前分钟内,还可以执行10 个请求。
使用Plotly 可视化仓库
import requests
from plotly import offline
# 执行API 调用并存储响应。
url = 'https://api.github.com/search/repositories?q=language:python&sort=stars'
headers = {'Accept': 'application/vnd.github.v3+json'}
r = requests.get(url, headers=headers)
print(f"Status code: {r.status_code}")
# 处理结果。
response_dict = r.json()
repo_dicts = response_dict['items']
repo_names, stars = [], []
for repo_dict in repo_dicts:
repo_names.append(repo_dict['name'])
stars.append(repo_dict['stargazers_count'])
# 可视化。
data = [{
'type': 'bar',
'x': repo_names,
'y': stars,
# marker 设置条形设计.
'marker': {
# 设置柱状图的填充颜色。
'color': 'rgb(60, 100, 150)',
# 设置条形边框的颜色和粗细。
'line': {'width': 1.5, 'color': 'rgb(25,25,25)'},
},
'opacity': 0.6,
}]
my_layout = {
'title': 'GitHub上最受欢迎的Python项目。',
'xaxis': {'title': 'Rrepository',
# X轴标题大小。
'titlefont': {'size': 24},
# X 轴刻度字体大小。
'tickfont': {'size': 14},
},
'yaxis': {'title': 'Stars',
# y 轴标题大小。
'titlefont': {'size': 24},
# X 轴刻度字体大小。
'tickfont': {'size': 14},
},
}
fig = {'data': data, 'layout': my_layout}
offline.plot(fig, filename='python_repos.html')
添加自定义工具提示
当前显示的是项目获得了多少个星。下面来创建自定义工具提示,以显示项目的描述和所有者。
import requests
from plotly import offline
# 执行API 调用并存储响应。
url = 'https://api.github.com/search/repositories?q=language:python&sort=stars'
headers = {'Accept': 'application/vnd.github.v3+json'}
r = requests.get(url, headers=headers)
print(f"Status code: {r.status_code}")
# 处理结果。
response_dict = r.json()
repo_dicts = response_dict['items']
repo_names, stars, labels = [], [], []
for repo_dict in repo_dicts:
repo_names.append(repo_dict['name'])
stars.append(repo_dict['stargazers_count'])
# 从每个项目中获取用户,和项目的描述信息。
owner = repo_dict['owner']['login']
desciption = repo_dict['description']
# 拼接成一个段落
label = f"{owner}<br />{desciption}"
# 添加到labels 列表中。
labels.append(label)
# 可视化。
data = [{
'type': 'bar',
'x': repo_names,
'y': stars,
# 条形的自定义显示文本。
'hovertext': labels,
# marker 设置条形设计.
'marker': {
# 设置柱状图的填充颜色。
'color': 'rgb(60, 100, 150)',
# 设置条形边框的颜色和粗细。
'line': {'width': 1.5, 'color': 'rgb(25,25,25)'},
},
'opacity': 0.6,
}]
my_layout = {
'title': 'GitHub上最受欢迎的Python项目。',
'xaxis': {'title': 'Rrepository',
# X轴标题大小。
'titlefont': {'size': 24},
# X 轴刻度字体大小。
'tickfont': {'size': 14},
},
'yaxis': {'title': 'Stars',
# y 轴标题大小。
'titlefont': {'size': 24},
# X 轴刻度字体大小。
'tickfont': {'size': 14},
},
}
fig = {'data': data, 'layout': my_layout}
offline.plot(fig, filename='python_repos.html')
在图表中添加客单击的链接
import requests
from plotly import offline
# 执行API 调用并存储响应。
url = 'https://api.github.com/search/repositories?q=language:python&sort=stars'
headers = {'Accept': 'application/vnd.github.v3+json'}
r = requests.get(url, headers=headers)
print(f"Status code: {r.status_code}")
# 处理结果。
response_dict = r.json()
repo_dicts = response_dict['items']
repo_names, stars, labels, repo_links = [], [], [], []
for repo_dict in repo_dicts:
repo_names.append(repo_dict['name'])
# 生成linkes 存入到repo_links 列表中。
repo_name = repo_dict['name']
repo_url = repo_dict['html_url']
# 这里使用了HTML 语法,创建了一个HTML 链接,显示名称为repo_name ,指向 对应项目链接。
repo_link = f"<a href='{repo_url}' > {repo_name} </a>"
repo_links.append(repo_link)
# stars
stars.append(repo_dict['stargazers_count'])
# 从每个项目中获取用户,和项目的描述信息。
owner = repo_dict['owner']['login']
desciption = repo_dict['description']
# 拼接成一个段落
label = f"{owner}<br />{desciption}"
# 添加到labels 列表中。
labels.append(label)
# 可视化。
data = [{
'type': 'bar',
'x': repo_links,
'y': stars,
# 条形的自定义显示文本。
'hovertext': labels,
# marker 设置条形设计.
'marker': {
# 设置柱状图的填充颜色。
'color': 'rgb(60, 100, 150)',
# 设置条形边框的颜色和粗细。
'line': {'width': 1.5, 'color': 'rgb(25,25,25)'},
},
'opacity': 0.6,
}]
my_layout = {
'title': 'GitHub上最受欢迎的Python项目。',
'xaxis': {'title': 'Rrepository',
# X轴标题大小。
'titlefont': {'size': 24},
# X 轴刻度字体大小。
'tickfont': {'size': 14},
},
'yaxis': {'title': 'Stars',
# y 轴标题大小。
'titlefont': {'size': 24},
# X 轴刻度字体大小。
'tickfont': {'size': 14},
},
}
fig = {'data': data, 'layout': my_layout}
offline.plot(fig, filename='python_repos.html')
深入了解Plotly he GitHub API
API#GITHUB API 说明链接
Getting started with plotly in Python
Hacker News API
分析Hacker News 网站的API
让返回的JSON 更好阅读
import requests
import json
# 执行API 调用并存储响应。
url = 'https://hacker-news.firebaseio.com/v0/item/19155826.json'
response = requests.get(url)
print(f"Status code: {response.status_code}")
# 探索数据的结构。
response_dict = response.json()
print(response_dict)
file_name = 'data/readable_hn_data.json'
with open(file_name,'w') as file_object:
json.dump(response_dict, file_object, indent=4)
返回的信息
{
"by": "jimktrains2",
"descendants": 221,
"id": 19155826,
"kids": [
19156572,
19158857,
19156773,
19157251,
19156415,
--snip--
],
"score": 728,
"time": 1550085414,
"title": "Nasa\u2019s Mars Rover Opportunity Concludes a 15-Year Mission",
"type": "story",
"url": "https://www.nytimes.com/2019/02/13/science/mars-opportunity-rover-dead.html"
}
| key | 说明 |
|---|---|
| "by": "jimktrains2" | 作者 |
| "descendants": 221 | 评论数 |
| "kids": | 列表 |
| "score": 728 | 评分 |
| "time": 1550085414 | 时间 |
| "title": | 文章的标题 |
| "type": | 文章的类型 |
| "url": | 文章的链接 |
练习题
import requests
from plotly import offline
language = 'JavaScript'
# 执行API 调用并存储响应。
url = f"https://api.github.com/search/repositories?q=language:{language}&sort=stars"
headers = {'Accept': 'application/vnd.github.v3+json'}
r = requests.get(url, headers=headers)
print(f"Status code: {r.status_code}")
# 处理结果。
response_dict = r.json()
repo_dicts = response_dict['items']
repo_names, stars, labels, repo_links = [], [], [], []
for repo_dict in repo_dicts:
repo_names.append(repo_dict['name'])
# 生成linkes 存入到repo_links 列表中。
repo_name = repo_dict['name']
repo_url = repo_dict['html_url']
# 这里使用了HTML 语法,创建了一个HTML 链接,显示名称为repo_name ,指向 对应项目链接。
repo_link = f"<a href='{repo_url}' > {repo_name} </a>"
repo_links.append(repo_link)
# stars
stars.append(repo_dict['stargazers_count'])
# 从每个项目中获取用户,和项目的描述信息。
owner = repo_dict['owner']['login']
desciption = repo_dict['description']
# 拼接成一个段落
label = f"{owner}<br />{desciption}"
# 添加到labels 列表中。
labels.append(label)
# 可视化。
data = [{
'type': 'bar',
'x': repo_links,
'y': stars,
# 条形的自定义显示文本。
'hovertext': labels,
# marker 设置条形设计.
'marker': {
# 设置柱状图的填充颜色。
'color': 'rgb(60, 100, 150)',
# 设置条形边框的颜色和粗细。
'line': {'width': 1.5, 'color': 'rgb(25,25,25)'},
},
'opacity': 0.6,
}]
my_layout = {
'title': f"GitHub上最受欢迎的{language}项目。",
'xaxis': {'title': 'Rrepository',
# X轴标题大小。
'titlefont': {'size': 24},
# X 轴刻度字体大小。
'tickfont': {'size': 14},
},
'yaxis': {'title': 'Stars',
# y 轴标题大小。
'titlefont': {'size': 24},
# X 轴刻度字体大小。
'tickfont': {'size': 14},
},
}
fig = {'data': data, 'layout': my_layout}
offline.plot(fig, filename='python_repos.html')
from operator import itemgetter
from plotly import offline
import requests
# 执行API 调用并存储响应。
url = 'https://hacker-news.firebaseio.com/v0/topstories.json'
response_top = requests.get(url)
print(f"Status code: {response_top.status_code}")
# 处理有关每篇文章的信息。
submission_ids = response_top.json()
submission_dicts = []
for submission_id in submission_ids[:30]:
# 对于每篇文章,都执行一个API调用。
url = f"https://hacker-news.firebaseio.com/v0/item/{submission_id}.json"
response = requests.get(url)
print(f"id: {submission_id}\tstatus: {response.status_code}")
response_dict = response.json()
# 对于每篇文章,都创建一部字典。
submission_dict = {
'by': response_dict['by'],
'title': response_dict['title'],
'hn_link': f"https://news.ycombinator.com/item?id={submission_id}",
'comments': response_dict['descendants'],
}
submission_dicts.append(submission_dict)
submission_dicts = sorted(submission_dicts, key=itemgetter('comments'), reverse=True)
titles, comments, hn_links, bys, labels = [], [], [], [], []
for submission_dict in submission_dicts:
titles.append(submission_dict['title'])
hn_links.append(submission_dict['hn_link'])
comments.append(submission_dict['comments'])
bys.append(submission_dict['by'])
# label setting
title = submission_dict['title']
hn_link = submission_dict['hn_link']
label = f"{title}<br />{hn_link}"
labels.append(label)
# 可视化。
data = [{
'type': 'bar',
'x': bys,
'y': comments,
# 条形的自定义显示文本。
'hovertext': labels,
# marker 设置条形设计.
'marker': {
# 设置柱状图的填充颜色。
'color': 'rgb(60, 100, 150)',
# 设置条形边框的颜色和粗细。
'line': {'width': 1.5, 'color': 'rgb(25,25,25)'},
},
'opacity': 0.6,
}]
my_layout = {
'title': 'hn news ',
'xaxis': {'title': 'Rrepository',
# X轴标题大小。
'titlefont': {'size': 24},
# X 轴刻度字体大小。
'tickfont': {'size': 14},
},
'yaxis': {'title': 'Stars',
# y 轴标题大小。
'titlefont': {'size': 24},
# X 轴刻度字体大小。
'tickfont': {'size': 14},
},
}
fig = {'data': data, 'layout': my_layout}
offline.plot(fig, filename='python_repos.html')